﻿
-----------------------------------------------------------------------
-- MatrixCommand.lua
--
-- A Framework for World Of Warcraft addons
-- Copyright (C) 2007  wwkkii
-- 
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- any later version.
-- 
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- GNU General Public License for more details.
-- 
-- You should have received a copy of the GNU General Public License
-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
-- 
-- Home Page: http://code.google.com/p/wowmatrix
-----------------------------------------------------------------------

local __version__ = { "MatrixCommand", 0, 1, 1 };
if (MatrixUpdateVersion(__version__)) then return; end

-------------------------------------------------------------------------------
-- Command Interface
-------------------------------------------------------------------------------

MatrixInterface("MatrixCommand");

function MatrixCommand:InitialCommand(prefix)
	if (not matrix.IsKeyName(prefix)) then
		self.cmd_prefix = "OnCommand";
	else
		self.cmd_prefix = prefix;
	end
	self.cmd_callbacks = { };
end

function MatrixCommand:CleanupCommand()
	local idx, key;

	self.cmd_prefix = nil;
	self.cmd_callbacks = nil;
	if (self.cmd_binding) then
		key = string.upper(self.cmd_binding);
		for idx = 1, 9, 1 do
			setglobal("SLASH_"..key..idx, nil);
		end
		SlashCmdList[key] = nil;
		self.cmd_binding = nil;
	end
end

function MatrixCommand:BindingSlash(name)
	local key;

	if (not self.cmd_binding) then
		self.cmd_binding = name;
		key = string.upper(name);
		setglobal("SLASH_"..key.."1", "/"..name);
		SlashCmdList[key] = self;
	end
end

function MatrixCommand:AliasCommand(name)
	local idx, key;

	if (not self.cmd_binding) then
		self:Error("ERROR_ALIAS_DENIED");
	end
	key = toupper(self.cmd_binding);
	for idx = 1, 9, 1 do
		if (getglobal("SLASH_"..key..idx) == nil) then
			setglobal("SLASH_"..key.._idx, "/"..self.cmd_binding);
			return;
		end
	end
end

function MatrixCommand:RegisterCommand(name, cbname)
	if (not self.cmd_prefix) then
		self:InitialCommand();
	end
	if (not matrix.IsName(name)) then
		self:Crash("ERROR_BAD_NAME", "Command", name);
	end
	if (not matrix.IsKeyName(cbname)) then
		cbname = self.cmd_prefix..matrix.ToWord(name);
	end
	self.cmd_callbacks[name] = cbname;
	if (not self[cbname]) then
		self[cbname] = function() end;
	end
end

function MatrixCommand:UnregisterCommand(name)
	self.cmd_callbacks[name] = nil;
end

function MatrixCommand:UnregisterAllCommands()
	self.cmd_callbacks = { };
end

function MatrixCommand:ExecuteCommand(cmd)
	local subcmd, subarg;
	local pos, epos;
	local callback;

	if ((cmd == nil) or (cmd == "")) then
		self:OnDefaultCommand();
		return;
	end

	subarg = "";
	callback = self.cmd_callbacks[cmd];
	if (callback == nil) then
		pos, epos, subcmd, subarg = string.find(cmd, "%s*([^%s]+)%s+(.*)");
		if (pos and epos and subcmd) then
			cmd = subcmd;
			callback = self.cmd_callbacks[subcmd];
		end
	end
	if (callback) then
		self:Invoke(callback, subarg, cmd);
	elseif (cmd == "help") then
		self:OnHelpCommand(subarg);
	else
		self:OnUnknownCommand(cmd, subarg);
	end
end

function MatrixCommand:OnDefaultCommand()
	self:OnHelpCommand(nil);
end

function MatrixCommand:OnUnknownCommand(cmd, arg)
	self:Error("command ("..cmd..") not found.");
end

function MatrixCommand:OnHelpCommand(cmd)
	local key;

	if ((cmd == nil) or (cmd == "")) then
		matrix.Print(self:Name().." commands:");
		for key in pairs(self.cmd_callbacks) do
			matrix.Print("    "..key..": command "..key);
		end
		return;
	end
	if (self.cmd_callbacks[cmd] == nil) then
		matrix.Print("Unknown command ("..cmd..")");
	else
		matrix.Print(cmd..": command "..cmd);
	end
end
